---
title: 'Astro DB'
description: Astro専用に設計されたフルマネージドSQLデータベース、Astro DBの使い方について学びます。
githubIntegrationURL: 'https://github.com/withastro/astro/tree/main/packages/db/'
i18nReady: true
---
import { FileTree } from '@astrojs/starlight/components';
import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro';
import ReadMore from '~/components/ReadMore.astro';
import StudioHeading from '~/components/StudioHeading.astro';

Astro DBは、Astro専用に設計されたフルマネージドSQLデータベースです。ローカルでの開発も、[Astro Studio](/ja/recipes/studio/)プラットフォームで管理されているホストされたデータベースへの接続も可能です。

## インストール

（`v0.8.1`以降の）[`@astrojs/db`インテグレーション](/ja/guides/integrations-guide/db/)を使用して、新しいAstroプロジェクトまたは既存のプロジェクト（`astro@4.5`以降が必要です）にAstro DBを追加します。Astroには、このセットアッププロセスを自動化するための組み込みの`astro add`コマンドが含まれています。

<PackageManagerTabs>
  <Fragment slot="npm">
  ```sh
  npx astro add db
  ```
  </Fragment>
  <Fragment slot="pnpm">
  ```sh
  pnpm astro add db
  ```
  </Fragment>
  <Fragment slot="yarn">
  ```sh
  yarn astro add db
  ```
  </Fragment>
</PackageManagerTabs>

必要に応じて、[`@astrojs/db`の手動インストール](/ja/guides/integrations-guide/db/#manual-installation)も可能です。

## データベースの定義

Astro DBは、データの設定、開発、およびクエリをおこなうための完全なソリューションです。`astro dev`の実行ごとにローカルデータベースが作成されますが、LibSQLを使用してデータを管理するため、Dockerやネットワーク接続は必要ありません。

`astro add`コマンドで`@astrojs/db`をインストールすると、プロジェクトに`db/config.ts`ファイルが作成されます。ここにデータベースのテーブルを定義します。

```ts title="db/config.ts"
import { defineDb } from 'astro:db';

export default defineDb({
  tables: { },
})
```

### テーブル

Astro DBでは、データはSQLテーブルを使用して保存されます。テーブルはデータを行と列に構造化し、列は各行の値の型を強制します。

テーブルを定義すると、プロジェクトからそのテーブルにクエリするためのTypeScriptのインターフェースが、Astroによって生成されます。これにより、データにアクセスする際に、プロパティの自動補完や型チェックなどの完全なTypeScriptのサポートが得られます。

データベーステーブルを設定するには、`astro:db`から`defineTable()`と`column`ユーティリティをインポートして使用します。

以下の例では、必須のテキストカラム`author`と`body`をもつ`Comment`テーブルを設定しています。そして、`defineDb()`をエクスポートしてプロジェクトで利用できるようにします。

```ts title="db/config.ts" "Comment"
import { defineDb, defineTable, column } from 'astro:db';

const Comment = defineTable({
  columns: {
    author: column.text(),
    body: column.text(),
  }
})

export default defineDb({
  tables: { Comment },
})
```

<ReadMore>テーブルのオプションの完全なリファレンスについては、[テーブルの設定リファレンス](/ja/guides/integrations-guide/db/#table-configuration-reference)を参照してください。</ReadMore>

### カラム

Astro DBは、次のカラム型をサポートしています。

```ts title="db/config.ts" "column.text()" "column.number()" "column.boolean()" "column.date()" "column.json()"
import { defineTable, column } from 'astro:db';

const Comment = defineTable({
  columns: {
    // テキストの文字列。
    author: column.text(),
    // 整数値。
    likes: column.number(),
    // 真偽値。
    flagged: column.boolean(),
    // JavaScriptのDateオブジェクトとしてクエリされる、日付/時刻の値。
    published: column.date(),
    // 型のないJSONオブジェクト。
    metadata: column.json(),
  }
});
```

<ReadMore>詳細については、[テーブルカラムのリファレンス](/ja/guides/integrations-guide/db/#table-configuration-reference)を参照してください。</ReadMore>

### テーブルの参照

テーブル間のリレーションは、データベース設計における一般的なパターンです。たとえば、`Blog`テーブルは`Comment`や`Author`、`Category`など、他のテーブルと密接に関連しているかもしれません。

**参照カラム**により、こうしたテーブル間のリレーションを定義し、データベーススキーマに保存できます。リレーションを設定するには、以下が必要です。

- 参照されるテーブルの**識別子カラム**。通常、`primaryKey`プロパティをもつ`id`カラムです。
- **参照される`id`を格納**する、参照元テーブルのカラム。`references`プロパティによりリレーションを設定します。

以下の例では、`Comment`テーブルの`authorId`カラムが`Author`テーブルの`id`カラムを参照しています。

```ts title="db/config.ts" {3, 10}
const Author = defineTable({
  columns: {
    id: column.number({ primaryKey: true }),
    name: column.text(),
  }
});

const Comment = defineTable({
  columns: {
    authorId: column.number({ references: () => Author.columns.id }),
    content: column.text(),
  }
});
```

## データベースのシード

開発中、AstroはDBの設定を使用して、スキーマに従ってローカルに型を生成します。これらの型は開発サーバーが起動するたびに新たに生成されるため、型安全性と自動補完のもとで、データの形状をクエリしたり操作したりできます。

テストやデバッグのために開発データをAstroプロジェクトにシードするには、`db/seed.ts`ファイルを作成します。`astro:db`から`db`オブジェクトと設定済みのテーブルをインポートし、`db.insert()`関数を使用してテーブルの行データオブジェクトの配列を与えます。

以下の例では、`Comment`テーブルに2行の開発用データを定義しています。

```ts title="db/seed.ts"
import { db, Comment } from 'astro:db';

export default async function() {
  await db.insert(Comment).values([
    { authorId: 1, body: 'Astro DBを気に入ってもらえると嬉しいです！' },
    { authorId: 2, body: '楽しんでください！'},
  ])
}
```

このファイルが変更されるたびに、開発サーバーは自動的にデータベースを再起動し、型を再生成して`seed.ts`から開発データをシードします。

## データベースへのクエリ

プロジェクト内の任意の[Astroページ](/ja/basics/astro-pages/#astroページ)や[エンドポイント](/ja/guides/endpoints/)から、提供される`db` ORMとクエリビルダーを使用してデータベースへのクエリができます。

### Drizzle ORM

```
import { db } from 'astro:db';
```

Astro DBには、組み込みの[Drizzle ORM](https://orm.drizzle.team/)クライアントが含まれています。このクライアントを使用するためのセットアップや手動の設定は必要ありません。Astro DBの`db`クライアントは、Astroを実行すると（ローカルまたはリモートの）データベースと通信するように自動的に設定されます。また、データベーススキーマの定義を正確に使用して型安全なSQLクエリが可能になるため、存在しないカラムやテーブルを参照するとTypeScriptエラーが発生します。

### Select

以下の例では、`Comment`テーブルのすべての行を選択しています。これにより、`db/seed.ts`からシードされた開発データの配列全体が返され、ページのテンプレートで使用できるようになります。

```astro title="src/pages/index.astro"
---
import { db, Comment } from 'astro:db';

const comments = await db.select().from(Comment);
---

<h2>コメント</h2>

{
  comments.map(({ author, body }) => (
    <article>
      <p>著者: {author}</p>
      <p>{body}</p>
    </article>
  ))
}
```

<ReadMore>より詳しい情報については、[Drizzle `select()`のAPIリファレンス](https://orm.drizzle.team/docs/select)を参照してください。</ReadMore>

### Insert

フォームからのリクエストを処理してリモートにホストされたデータベースにデータを挿入する場合のように、ユーザー入力を受け付けるためには、Astroプロジェクトを[オンデマンドレンダリング](/ja/basics/rendering-modes/#オンデマンドレンダリング)に設定し、デプロイ環境向けの[SSRアダプターを追加](/ja/guides/server-side-rendering/#公式アダプター)してください。

この例では、パースされたフォームのPOSTリクエストに基づいて、`Comment`テーブルに行を挿入しています。

```astro
---
// src/pages/index.astro
import { db, Comment } from 'astro:db';

if (Astro.request.method === 'POST') {
  // フォームデータのパース
  const formData = await Astro.request.formData();
  const author = formData.get('author');
  const content = formData.get('content');
  if (typeof author === 'string' && typeof content === 'string') {
    // フォームデータをCommentテーブルに挿入
    await db.insert(Comment).values({ author, content });
  }
}

// リクエストごとに新しいコメントのリストをレンダリング
const comments = await db.select().from(Comment);
---

<form method="POST" style="display: grid">
	<label for="author">著者</label>
	<input id="author" name="author" />

	<label for="content">コンテンツ</label>
	<textarea id="content" name="content"></textarea>

	<button type="submit">送信</button>
</form>

<!--`comments`をレンダリング-->
```

APIエンドポイントからデータベースをクエリすることも可能です。この例では、`id`パラメータによって`Comment`テーブルから行を削除しています。

```ts
// src/pages/api/comments/[id].ts
import type { APIRoute } from "astro";
import { db, Comment, eq } from 'astro:db';

export const DELETE: APIRoute = async (ctx) => {
  await db.delete(Comment).where(eq(Comment.id, ctx.params.id ));
  return new Response(null, { status: 204 });
}
```

<ReadMore>より詳しい情報については、[Drizzle `insert()`のAPIリファレンス](https://orm.drizzle.team/docs/insert)を参照してください。</ReadMore>

### フィルタリング

特定のプロパティによってテーブルの結果をクエリするには、[部分選択（partial select）のためのDrizzleオプション](https://orm.drizzle.team/docs/select#partial-select)を使用します。たとえば、`select()`クエリに[`.where()`呼び出し](https://orm.drizzle.team/docs/select#filtering)を追加し、必要な比較条件を渡します。

以下の例では、「Astro DB」というフレーズを含む`Comment`テーブルのすべての行をクエリしています。`body`内にフレーズが存在するかどうかをチェックするためには、[`like()`オペレータ](https://orm.drizzle.team/docs/operators#like)を使用します。


```astro title="src/pages/index.astro"
---
import { db, Comment, like } from 'astro:db';

const comments = await db.select().from(Comment).where(
    like(Comment.body, '%Astro DB%')
);
---
```

### Drizzleのユーティリティ

クエリのビルドに使用するDrizzleユーティリティはすべて、`astro:db`モジュールから公開されています。これには以下が含まれます。

- `eq()`や`gt()`などの[フィルタオペレータ](https://orm.drizzle.team/docs/operators)
- `count()`などの[集計用ヘルパー](https://orm.drizzle.team/docs/select#aggregations-helpers)
- 生のSQLクエリを書くための[`sql`ヘルパー](https://orm.drizzle.team/docs/sql)

```ts
import { eq, gt, count, sql } from 'astro:db';
```

### リレーション

SQLの結合を使用して、複数のテーブルから関連するデータをクエリできます。結合クエリを作成するには、`db.select()`文を結合演算子で拡張します。各関数は、結合するテーブルと、2つのテーブル間の行を一致させる条件を受け付けます。

この例では、`innerJoin()`関数を使用して、`Comment`の著者を`authorId`カラムに基づいて関連する`Author`情報と結合しています。これにより、各`Author`と`Comment`行をトップレベルのプロパティとしてもつオブジェクトの配列が返されます。

```astro title="src/pages/index.astro"
---
import { db, eq, Comment, Author } from 'astro:db';

const comments = await db.select()
  .from(Comment)
  .innerJoin(Author, eq(Comment.authorId, Author.id));
---

<h2>コメント</h2>

{
  comments.map(({ Author, Comment }) => (
    <article>
      <p>著者: {Author.name}</p>
      <p>{Comment.body}</p>
    </article>
  ))
}
```

<ReadMore>利用可能なすべての結合演算子と設定オプションについては、[Drizzleの結合リファレンス](https://orm.drizzle.team/docs/joins#join-types)を参照してください。</ReadMore>

### トランザクションのバッチ処理

リモートデータベースへのクエリはすべてネットワークリクエストとして実行されます。大量のクエリを実行する場合や、クエリが失敗した場合に自動的にロールバックするために、複数のクエリを1つのトランザクションへとまとめる必要がある場合があります。

この例では、`db.batch()`メソッドを使用して、1つのリクエストで複数の行をシードしています。

```ts
// db/seed.ts
import { db, Author, Comment } from 'astro:db';

export default async function () {
  const queries = [];
  // 100件のサンプルコメントを1回のネットワークリクエストで
  // リモートデータベースにシードします。
  for (let i = 0; i < 100; i++) {
    queries.push(db.insert(Comment).values({ body: `テストコメント ${i}` }));
  }
  await db.batch(queries);
}
```

<ReadMore>詳細については、[Drizzle `db.batch()`](https://orm.drizzle.team/docs/batch-api)のドキュメントを参照してください。</ReadMore>

<StudioHeading>
## Astro Studio
</StudioHeading>

Astro DBは、[Astro Studioプラットフォームに接続](/ja/recipes/studio/)して、ホストされたデータベースをプロジェクトに迅速に追加できます。Astro Studioのダッシュボードから、新しくホストされたデータベースを表示、管理、デプロイできます。

新しいプロジェクトを作成するには、[既成のテンプレート](https://studio.astro.build)を使用するか、[Astro Studioガイド](/ja/recipes/studio/#create-a-new-studio-project)を確認してください。

<StudioHeading>
### テーブルスキーマのプッシュ
</StudioHeading>

プロジェクトが成長するにつれて、テーブルスキーマは変化します。ローカルで設定の変更を安全にテストした上で、デプロイ時にStudioのデータベースにプッシュできます。

[ダッシュボードからStudioプロジェクトを作成](#astro-studio)する際、GitHubのCIアクションを作成するオプションがあります。これを使うと、リポジトリのメインブランチにマージする際に、スキーマの変更が自動的にマイグレーションされます。

また、`astro db push`コマンドにより、CLIを通じてスキーマの変更をプッシュすることも可能です。

<PackageManagerTabs>
  <Fragment slot="npm">
  ```sh
  npm run astro db push
  ```
  </Fragment>
  <Fragment slot="pnpm">
  ```sh
  pnpm astro db push
  ```
  </Fragment>
  <Fragment slot="yarn">
  ```sh
  yarn astro db push
  ```
  </Fragment>
</PackageManagerTabs>

このコマンドは、データの損失なしに変更が可能であるかを検証し、コンフリクトを解消するための推奨されるスキーマ変更についてガイドします。破壊的なスキーマ変更をおこなう必要がある場合は、`--force-reset`フラグを追加してすべての本番データをリセットしてください。

<StudioHeading>
### データのプッシュ
</StudioHeading>

シードやデータのマイグレーションのために、Studioのデータベースにデータをプッシュする必要がある場合があります。これには、`astro:db`モジュールを使用して`.ts`ファイルを作成し型安全なクエリを書いた上で、`astro db execute <file-path> --remote`コマンドにより、ファイルをStudioデータベースに対して実行します。

以下のCommentsは、`astro db execute db/seed.ts --remote`コマンドを使用してシードできます。

```ts
// db/seed.ts
import { Comment } from 'astro:db';

export default async function () {
  await db.insert(Comment).values([
    { authorId: 1, body: 'Astro DBを気に入ってもらえると嬉しいです！' },
    { authorId: 2, body: '楽しんでください！' },
  ])
}
```

<ReadMore>コマンドの完全なリストについては、[CLIリファレンス](/ja/guides/integrations-guide/db/#astro-db-cli-reference)を参照してください。</ReadMore>

<StudioHeading>
### Astro Studioへの接続
</StudioHeading>

デフォルトでは、`dev`または`build`コマンドを実行すると、Astroはローカルのデータベースファイルを使用します。各コマンドが実行されるたびにテーブルがゼロから再作成され、開発用のシードデータが挿入されます。

ホストされているStudioのデータベースに接続するには、`--remote`フラグを追加します。本番環境でのデプロイにこのフラグを使用すると、Studioデータベースへの読み書きアクセスが可能になります。これにより、[ユーザーデータを受け入れて永続化](#insert)できます。

```bash
# リモートに接続してビルド
astro build --remote

# リモートに接続して開発
astro dev --remote
```

:::caution

開発中に`--remote`を使用する際は注意してください。これにより、稼働中の本番データベースに接続され、すべての挿入、更新、削除が永続化されます。

:::

リモート接続を使用するには、Studioとの認証に使用するアプリトークンが必要です。トークンの作成と設定手順については、Studioダッシュボードを確認してください。

<ReadMore>デプロイの準備ができたら、[Studioと接続してデプロイするためのガイド](/ja/recipes/studio/#deploy-with-a-studio-connection)を参照してください。</ReadMore>

## Astro DBインテグレーションの作成

[Astroインテグレーション](/ja/reference/integrations-reference/)により、Astro DBテーブルとシードデータを追加してユーザープロジェクトを拡張できます。

`astro:db:setup`フック内で`extendDb()`メソッドを使用して、追加のAstro DB設定とシードファイルを登録します。`defineDbIntegration()`ヘルパーは、`astro:db:setup`フックに対してTypeScriptサポートと自動補完を提供します。

```js {8-13}
// my-integration/index.ts
import { defineDbIntegration } from '@astrojs/db/utils';

export default function MyIntegration() {
  return defineDbIntegration({
    name: 'my-astro-db-powered-integration',
    hooks: {
      'astro:db:setup': ({ extendDb }) => {
        extendDb({
          configEntrypoint: '@astronaut/my-package/config',
          seedEntrypoint: '@astronaut/my-package/seed',
        });
      },
      // 他のインテグレーションフック...
    },
  });
}
```

インテグレーションの[設定](#データベースの定義)と[シード](#データベースのシード)ファイルは、ユーザー定義のものと同じフォーマットに従います。

### インテグレーションでの型安全な操作

インテグレーションでの作業中、`astro:db`からエクスポートされる、Astroが生成したテーブル型を利用できないことがあります。完全な型安全性を確保するためには、`asDrizzleTable()`ユーティリティを使用して、データベース操作に使用するテーブル参照オブジェクトを作成します。

たとえば、次の`Pets`というデータベーステーブルを定義するインテグレーションがあるとします。

```js
// my-integration/config.ts
import { defineDb, defineTable, column } from 'astro:db';

export const Pets = defineTable({
  columns: {
    name: column.text(),
    species: column.text(),
  },
});

export default defineDb({ tables: { Pets } });
```

シードファイルで`Pets`をインポートして`asDrizzleTable()`を使用すると、テーブルに行を挿入する際に型チェックをおこなえます。

```js {2,7} /typeSafePets(?! )/
// my-integration/seed.ts
import { asDrizzleTable } from '@astrojs/db/utils';
import { db } from 'astro:db';
import { Pets } from './config';

export default async function() {
  const typeSafePets = asDrizzleTable('Pets', Pets);

  await db.insert(typeSafePets).values([
    { name: 'Palomita', species: 'cat' },
    { name: 'Pan', species: 'dog' },
  ]);
}
```

`asDrizzleTable('Pets', Pets)`から返される値は、`import { Pets } from 'astro:db'`と同等ですが、Astroの型生成が実行できないような場合でも利用できます。データベースへのクエリや挿入が必要なインテグレーションコードで使用できます。
